package cn.congine.wizarpos.mall.action;

import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import cn.congine.wizarpos.mall.model.MrtMerchantCard;
import cn.congine.wizarpos.mall.model.MrtTicketDef;
import cn.congine.wizarpos.mall.model.MrtTicketInfo;
import cn.congine.wizarpos.mall.model.open.AccessTokenInput;
import cn.congine.wizarpos.mall.model.open.CommonResultOutput;
import cn.congine.wizarpos.mall.service.MrtMerchantCardService;
import cn.congine.wizarpos.mall.service.MrtTicketDefService;
import cn.congine.wizarpos.mall.service.MrtTicketInfoService;
import cn.congine.wizarpos.mall.service.SysMerchantDefService;
import cn.congine.wizarpos.mall.service.SysInTicketService;
import cn.congine.wizarpos.mall.service.SysWxChildMerchantTokenService;
import cn.congine.wizarpos.mall.service.impl.WPosHttpClient;
import cn.congine.wizarpos.mall.service.impl.WizarposOpenRestClient;
import cn.congine.wizarpos.mall.service.impl.WxAuthentication;
import cn.congine.wizarpos.mall.service.impl.WxThirdAuthentication;
import cn.congine.wizarpos.mall.utils.SysConstants;
import cn.congine.wizarpos.mall.utils.WxSignUtil;

import com.alibaba.fastjson.JSONObject;

@Controller
@RequestMapping(value = "/wx")
public class WeixinCardAction {
	private final Log log = LogFactory.getLog(getClass());

	@Resource(name = "messageSource")
	private MessageSource messageSource;

	@Autowired
	private WPosHttpClient wposHttpClient;

	@Autowired
	private SysMerchantDefService merchantDefService;

	@Autowired
	private SysInTicketService wxAccessTokenService;

	@Autowired
	private MrtTicketDefService mrtTicketDefService;

	@Autowired
	private MrtMerchantCardService mrtMerchantCardService;

	@Autowired
	private MrtTicketInfoService mrtTicketInfoService;

	@Autowired
	private WxThirdAuthentication wxAuthentication;

	@Autowired
	private  SysWxChildMerchantTokenService sysWxChildMerchantTokenService;
	
	@Autowired
	private WizarposOpenRestClient wizarposOpenRestClient;
	
	/**
	 * 创建微信卡券，暂未使用
	 * 
	 * @param mid
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/create_card_ticket")
	public @ResponseBody String createCard(
			@RequestParam(value = "mid", required = true) String mid)
			throws Exception {

		String createCardUrl = SysConstants.CREATE_CARD_URL.replace(
				SysConstants.ACCESS_TOKEN, wxAuthentication.getAccessToken(mid)
						.getAccessToken());

		JSONObject cardInfo = assembleCardInfo();

		JSONObject result = wposHttpClient.post(createCardUrl, cardInfo);

		System.out.println("---------weixin card_id----------");
		System.out.println(result.getString("card_id"));

		return result.getString("card_id");
	}

	/**
	 * 封装卡券信息
	 * 
	 * @return
	 */
	private JSONObject assembleCardInfo() {
		JSONObject base_info = new JSONObject();
		JSONObject groupon = new JSONObject();
		JSONObject card = new JSONObject();
		JSONObject json = new JSONObject();
		base_info
				.put("logo_url",
						"http://mmbiz.qpic.cn/mmbiz/nIA3TIjPY18lorOueVo14YwOrfHbib6LcXkCHkoSQ8UnZHGqws7oFoJZibW6s55Aj9rIibpbcOPL0yaDDWChcfbkw/0");
		base_info.put("brand_name", "无锡慧银信息");
		base_info.put("code_type", "CODE_TYPE_TEXT");
		base_info.put("title", "四人餐120元");
		base_info.put("color", "Color010");
		base_info.put("notice", "使用时向服务员出示此券");
		base_info.put("service_phone", "0510-83590630");
		base_info.put("description", "非常非常好，很棒");

		JSONObject date_info = new JSONObject();
		date_info.put("type", 1);
		date_info.put("begin_timestamp", WxSignUtil.createTimestamp());
		date_info.put("end_timestamp",
				WxSignUtil.createTimestamp() + 3600 * 24 * 30);
		date_info.put("fixed_term", 10);
		date_info.put("fixed_begin_term", 2);
		base_info.put("date_info", date_info);

		JSONObject sku = new JSONObject();
		sku.put("quantity", 50);
		base_info.put("sku", sku);

		base_info.put("get_limit", 3);
		base_info.put("use_custom_code", false);
		base_info.put("bind_openid", false);
		base_info.put("can_share", true);
		base_info.put("can_give_friend", true);

		base_info.put("url_name_type", "URL_NAME_TYPE_RESERVATION");
		base_info.put("custom_url", "http://www.wizarpos.com/");
		base_info.put("source", "无锡慧银信息");

		groupon.put("base_info", base_info);
		groupon.put("deal_detail", "非常棒，非常好");
		card.put("card_type", "GROUPON");
		card.put("groupon", groupon);
		json.put("card", card);

		System.out.println(json.toString());
		return json;
	}

	/**
	 * 创建卡券二维码，暂未使用
	 * 
	 * @param mid
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/create_qr_ticket")
	public @ResponseBody String createQRTicket(
			@RequestParam(value = "mid", required = true) String mid)
			throws Exception {
		String createQrUrl = SysConstants.CREATE_QR_URL.replace(
				SysConstants.ACCESS_TOKEN, wxAuthentication.getAccessToken(mid)
						.getAccessToken());

		JSONObject qrInfo = assembleQrInfo();

		JSONObject result = wposHttpClient.post(createQrUrl, qrInfo);

		System.out.println("---------QR ticket----------");
		System.out.println(result.getString("ticket"));

		return result.getString("ticket");
	}

	/**
	 * 封装卡券二维码信息
	 * 
	 * @return
	 */
	private JSONObject assembleQrInfo() {

		JSONObject card = new JSONObject();
		card.put("card_id", "pC_nujoNJ8pACuDi4kS8_PyZrssE");
		// card。put("code","yyMMddnum");
		// 指定卡券code码，只能被领一次。use_custom_code字段为true的卡券必须填写，非自定义code不必填写。
		// card.put("openid", "oC_nujuDKiu5DFb00T-j3WvTK_lw");
		// 指定领取者的openid，只有该用户能领取
		// card.put("expire_seconds", "1800"); 指定二维码的有效时间，范围是60 ~ 1800
		// 秒。不填默认为永久有效。
		// card.put("is_unique_code",
		// "false");指定下发二维码，生成的二维码随机分配一个code，领取后不可再次扫描。填写true 或false。默认false。
		// card.put("outer_id",
		// "1");领取场景值，用于领取渠道的数据统计，默认值为0，字段类型为整型。用户领取卡券后触发的事件推送中会带上此自定义场景值。

		JSONObject card_map = new JSONObject();
		card_map.put("card", card);

		JSONObject json = new JSONObject();
		json.put("action_name", "QR_CARD");
		json.put("action_info", card_map);

		return json;
	}

	/**
	 * 微信卡券的核销，暂未使用
	 * 
	 * @param mid
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/consume")
	public @ResponseBody String consume(
			@RequestParam(value = "mid", required = true) String mid)
			throws Exception {
		String consumeUrl = SysConstants.CONSUME_URL.replace(
				SysConstants.ACCESS_TOKEN, wxAuthentication.getAccessToken(mid)
						.getAccessToken());

		JSONObject consumeInfo = assembleConsumeInfo();

		JSONObject result = wposHttpClient.post(consumeUrl, consumeInfo);

		System.out.println("---------Consume Info----------");
		System.out.println(result.getString("openid"));

		return result.getString("ticket");
	}

	/**
	 * 微信卡券的核销，暂未使用
	 * 
	 * @param mid
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/get_wx_cord_id")
	public @ResponseBody String getCordId(
			@RequestParam(value = "mid", required = true) String mid)
			throws Exception {
		String cordIdUrl = SysConstants.CORD_ID_URL.replace(
				SysConstants.ACCESS_TOKEN, wxAuthentication.getAccessToken(mid)
						.getAccessToken());

		JSONObject cordIdInfo = assembleCordIdInfo();

		JSONObject result = wposHttpClient.post(cordIdUrl, cordIdInfo);

		System.out.println("---------get_wx_cord_id Info----------");
		System.out.println(result.getString("card_id"));

		return result.getString("card_id");
	}

	/**
	 * 封装卡券核销码信息
	 * 
	 * @return
	 */
	private JSONObject assembleCordIdInfo() {
		JSONObject json = new JSONObject();
		json.put("code", "292797871734");
		return json;
	}

	/**
	 * 封装卡券核销码信息
	 * 
	 * @return
	 */
	private JSONObject assembleConsumeInfo() {
		JSONObject json = new JSONObject();
		json.put("card_id", "pAab_tljL0K5m-_pYK4N_GhOGwEE");
		json.put("code", "292797871734");// 要消耗序列号，创建卡券时use_custom_code 填写true
		return json;
	}

	/**
	 * 获取商户下定义的微信卡券，暂未使用
	 * 
	 * @param mid
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/get_card_list")
	public @ResponseBody String getCardList(
			@RequestParam(value = "mid", required = true) String mid)
			throws Exception {
		String cardListUrl = SysConstants.CARD_LIST_URL.replace(
				SysConstants.ACCESS_TOKEN, wxAuthentication.getAccessToken(mid)
						.getAccessToken());

		JSONObject json = new JSONObject();
		json.put("offset", 0);
		json.put("count", 50);

		JSONObject result = wposHttpClient.post(cardListUrl, json);

		System.out.println("---------Card List Info----------");
		System.out.println(result.getString("total_num"));
		System.out.println(result.getString("card_id_list"));

		return result.getString("card_id_list");
	}

	/**
	 * 请求微信接口获取微信卡券详情，暂未使用
	 * 
	 * @param mid
	 * @param cardId
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/get_card_detail", method = RequestMethod.POST)
	public @ResponseBody String getCardDetail(
			@RequestParam(value = "mid", required = true) String mid,
			@RequestParam(value = "cardId", required = true) String cardId)
			throws Exception {
		String cardDetailUrl = SysConstants.CARD_DETAIL_URL.replace(
				SysConstants.ACCESS_TOKEN, wxAuthentication.getAccessToken(mid)
						.getAccessToken());

		JSONObject param = new JSONObject();
		param.put("card_id", cardId);
		JSONObject result = wposHttpClient.post(cardDetailUrl, param);

		if (result.getInteger("errcode") == 0) {
			JSONObject cardJson = result.getJSONObject("card");
			String cardType = cardJson.getString("card_type");
			JSONObject baseInfo = cardJson
					.getJSONObject(cardType.toLowerCase()).getJSONObject(
							"base_info");

			String status = null;
			switch (baseInfo.getString("status")) {
			case "CARD_STATUS_NOT_VERIFY":
				status = "待审核";
				break;
			case "CARD_STATUS_VERIFY_FALL":
				status = "审核失败";
				break;
			case "CARD_STATUS_VERIFY_OK":
				status = "通过审核";
				break;
			case "CARD_STATUS_USER_DELETE":
				status = "卡券被用户删除";
				break;
			case "CARD_STATUS_USER_ON_SHELF":
				status = "在公众平台投放过的卡券";
				break;
			}
			if ("CARD_STATUS_USER_DELETE".equals(baseInfo.getString("status"))) {
				return status;
			}
			return baseInfo.toJSONString();
		} else {
			return result.getString("errmsg");
		}
	}

	/**
	 * 领取微信卡券是添加到商户卡券
	 * 
	 * @param mid
	 * @param cardId
	 * @param code
	 * @param openid
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/give_ticket", method = RequestMethod.POST)
	public @ResponseBody String giveTicket(
			@RequestParam(value = "mid", required = true) String mid,
			@RequestParam(value = "cardId", required = true) String cardId,
			@RequestParam(value = "code", required = true) String code,
			@RequestParam(value = "openid", required = true) String openid)
			throws Exception {
		MrtTicketDef ticketDef = mrtTicketDefService.getByWxCardId(cardId);
		MrtMerchantCard MrtMerchantCard = mrtMerchantCardService
				.getMrtMerchantCard(mid, openid);
		MrtTicketInfo ticketInfo = new MrtTicketInfo();
		ticketInfo.setTicketId(ticketDef.getId());// 微信卡券号
		ticketInfo.setCardId(MrtMerchantCard.getId());
		ticketInfo.setTicketNo(code);

		mrtTicketInfoService.update(ticketInfo);

		return ticketInfo.getId();
	}

	/**
	 * 添加到微信卡包签名
	 * @param mid
	 * @param code
	 * @param openid
	 * @param timestamp
	 * @param cardid
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/get_ext_sign", method = RequestMethod.POST)
	public @ResponseBody String getExtSign(
			@RequestParam(value = "mid", required = true) String mid,
			@RequestParam(value = "code", required = true) String code,
			@RequestParam(value = "timestamp", required = true) String timestamp,
			@RequestParam(value = "cardid", required = true) String cardid)
			throws Exception {
		String openid = "";
		String ticket = null;
		AccessTokenInput jsInput = new AccessTokenInput();
		jsInput.setMid(mid);
		CommonResultOutput jsOutput = (CommonResultOutput) wizarposOpenRestClient.post(jsInput, "/weixin/ticket/card", CommonResultOutput.class);		
		if (jsOutput == null || SysConstants.OPEN_ERROR.equals(jsOutput.getCode())) {// 请求开放平台出错
			log.error("请求开放平台获取微信卡包签名失败");
		} else if (SysConstants.NO_MERCHANT_CODE.equals(jsOutput.getCode())) {// 非法的慧商户号
			log.error("非法的慧商户号");
		} else {
			Map<String, String> jsResult = (Map<String, String>) jsOutput.getResult();
		    ticket = jsResult.get("ticket");
		}
		if (ticket == null) {
			log.error("获取微信卡包签名失败");
			return "";
		}
	
		String signature = WxSignUtil.extSign(
				ticket, cardid, timestamp, code,
				openid);

		return signature;
	}

	/**
	 * 微信卡券签名
	 * 
	 * @param mid
	 * @param location_id
	 * @param timestamp
	 * @param nonceStr
	 * @param cardid
	 * @param cardType
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/get_card_sign", method = RequestMethod.POST)
	public @ResponseBody String getCardSign(
			@RequestParam(value = "mid", required = true) String mid,
			@RequestParam(value = "location_id", required = false) String location_id,
			@RequestParam(value = "timestamp", required = true) String timestamp,
			@RequestParam(value = "nonceStr", required = true) String nonceStr,
			@RequestParam(value = "cardid", required = false) String cardid,
			@RequestParam(value = "cardType", required = false) String cardType)
			throws Exception {

		if (location_id == null) {
			location_id = "";
		}
		if (cardid == null) {
			cardid = "";
		}
		if (cardType == null) {
			cardType = "";
		}

		String apiTicket = wxAuthentication.getCardTicket(mid);
		String appid = sysWxChildMerchantTokenService.getByWxAppIdAndMidAndPrimaryId(mid).getWxAppId();

		String signature = WxSignUtil.cardSign(apiTicket, appid, location_id,
				timestamp, nonceStr, cardid, cardType);

		return signature;
	}

}
